<!DOCTYPE html>
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
  <meta name="description" content="刘清政">
  <meta name="keyword" content="hexo-theme">
  
    <link rel="shortcut icon" href="/css/images/logo.png">
  
  <title>
    
      go/4-Go语言框架/4-1-gin框架/8-GORM增删查改 | Justin-刘清政的博客
    
  </title>
  <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <link href="//cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
  <link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/tomorrow.min.css" rel="stylesheet">
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/css/plugins/gitment.css">

  
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/geopattern/1.2.3/js/geopattern.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
  
    
<script src="/js/qrious.js"></script>

  
  
    
<script src="/js/gitment.js"></script>

  
  

  
<meta name="generator" content="Hexo 4.2.0"></head>
<div class="wechat-share">
  <img src="/css/images/logo.png" />
</div>

  <body>
    <header class="header fixed-header">
  <div class="header-container">
    <a class="home-link" href="/">
      <div class="logo"></div>
      <span>Justin-刘清政的博客</span>
    </a>
    <ul class="right-list">
      
        <li class="list-item">
          
            <a href="/" class="item-link">主页</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/tags/" class="item-link">标签</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/archives/" class="item-link">归档</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/about/" class="item-link">关于我</a>
          
        </li>
      
    </ul>
    <div class="menu">
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </div>
    <div class="menu-mask">
      <ul class="menu-list">
        
          <li class="menu-item">
            
              <a href="/" class="menu-link">主页</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/tags/" class="menu-link">标签</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/archives/" class="menu-link">归档</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/about/" class="menu-link">关于我</a>
            
          </li>
        
      </ul>
    </div>
  </div>
</header>

    <div id="article-banner">
  <h2>go/4-Go语言框架/4-1-gin框架/8-GORM增删查改</h2>



  <p class="post-date">2020-09-16</p>
    <!-- 不蒜子统计 -->
    <span id="busuanzi_container_page_pv" style='display:none' class="">
        <i class="icon-smile icon"></i> 阅读数：<span id="busuanzi_value_page_pv"></span>次
    </span>
  <div class="arrow-down">
    <a href="javascript:;"></a>
  </div>
</div>
<main class="app-body flex-box">
  <!-- Article START -->
  <article class="post-article">
    <section class="markdown-content"><p>CRUD通常指数据库的增删改查操作，本文详细介绍了如何使用GORM实现创建、查询、更新和删除操作。</p>
<h1 id="CRUD"><a href="#CRUD" class="headerlink" title="CRUD"></a>CRUD</h1><p>CRUD通常指数据库的增删改查操作，本文详细介绍了如何使用GORM实现创建、查询、更新和删除操作。</p>
<p>本文中的<code>db</code>变量为<code>*gorm.DB</code>对象，例如：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> (</span><br><span class="line">  <span class="string">"github.com/jinzhu/gorm"</span></span><br><span class="line">  _ <span class="string">"github.com/jinzhu/gorm/dialects/mysql"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">  db, err := gorm.Open(<span class="string">"mysql"</span>, <span class="string">"user:password@/dbname?charset=utf8&amp;parseTime=True&amp;loc=Local"</span>)</span><br><span class="line">  <span class="keyword">defer</span> db.Close()</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// db.Xx</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="创建"><a href="#创建" class="headerlink" title="创建"></a>创建</h2><h3 id="创建记录"><a href="#创建记录" class="headerlink" title="创建记录"></a>创建记录</h3><p>首先定义模型：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> User <span class="keyword">struct</span> &#123;</span><br><span class="line">	ID           <span class="keyword">int64</span></span><br><span class="line">	Name         <span class="keyword">string</span></span><br><span class="line">	Age          <span class="keyword">int64</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>使用使用<code>NewRecord()</code>查询主键是否存在，主键为空使用<code>Create()</code>创建记录：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">user := User&#123;Name: <span class="string">"q1mi"</span>, Age: <span class="number">18</span>&#125;</span><br><span class="line"></span><br><span class="line">db.NewRecord(user) <span class="comment">// 主键为空返回`true`</span></span><br><span class="line">db.Create(&amp;user)   <span class="comment">// 创建user</span></span><br><span class="line">db.NewRecord(user) <span class="comment">// 创建`user`后返回`false`</span></span><br></pre></td></tr></table></figure>

<h3 id="默认值"><a href="#默认值" class="headerlink" title="默认值"></a>默认值</h3><p>可以通过 tag 定义字段的默认值，比如：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> User <span class="keyword">struct</span> &#123;</span><br><span class="line">  ID   <span class="keyword">int64</span></span><br><span class="line">  Name <span class="keyword">string</span> <span class="string">`gorm:"default:'小王子'"`</span></span><br><span class="line">  Age  <span class="keyword">int64</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong>通过tag定义字段的默认值，在创建记录时候生成的 SQL 语句会排除没有值或值为 零值 的字段。 在将记录插入到数据库后，Gorm会从数据库加载那些字段的默认值。</p>
<p>举个例子：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> user = User&#123;Name: <span class="string">""</span>, Age: <span class="number">99</span>&#125;</span><br><span class="line">db.Create(&amp;user)</span><br></pre></td></tr></table></figure>

<p>上面代码实际执行的SQL语句是<code>INSERT INTO users(&quot;age&quot;) values(&#39;99&#39;);</code>，排除了零值字段<code>Name</code>，而在数据库中这一条数据会使用设置的默认值<code>小王子</code>作为Name字段的值。</p>
<p><strong>注意：</strong>所有字段的零值, 比如<code>0</code>, <code>&quot;&quot;</code>,<code>false</code>或者其它<code>零值</code>，都不会保存到数据库内，但会使用他们的默认值。 如果你想避免这种情况，可以考虑使用指针或实现 <code>Scanner/Valuer</code>接口，比如：</p>
<h4 id="使用指针方式实现零值存入数据库"><a href="#使用指针方式实现零值存入数据库" class="headerlink" title="使用指针方式实现零值存入数据库"></a>使用指针方式实现零值存入数据库</h4><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用指针</span></span><br><span class="line"><span class="keyword">type</span> User <span class="keyword">struct</span> &#123;</span><br><span class="line">  ID   <span class="keyword">int64</span></span><br><span class="line">  Name *<span class="keyword">string</span> <span class="string">`gorm:"default:'小王子'"`</span></span><br><span class="line">  Age  <span class="keyword">int64</span></span><br><span class="line">&#125;</span><br><span class="line">user := User&#123;Name: <span class="built_in">new</span>(<span class="keyword">string</span>), Age: <span class="number">18</span>))&#125;</span><br><span class="line">db.Create(&amp;user)  <span class="comment">// 此时数据库中该条记录name字段的值就是''</span></span><br></pre></td></tr></table></figure>

<h4 id="使用Scanner-Valuer接口方式实现零值存入数据库"><a href="#使用Scanner-Valuer接口方式实现零值存入数据库" class="headerlink" title="使用Scanner/Valuer接口方式实现零值存入数据库"></a>使用Scanner/Valuer接口方式实现零值存入数据库</h4><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用 Scanner/Valuer</span></span><br><span class="line"><span class="keyword">type</span> User <span class="keyword">struct</span> &#123;</span><br><span class="line">	ID <span class="keyword">int64</span></span><br><span class="line">	Name sql.NullString <span class="string">`gorm:"default:'小王子'"`</span> <span class="comment">// sql.NullString 实现了Scanner/Valuer接口</span></span><br><span class="line">	Age  <span class="keyword">int64</span></span><br><span class="line">&#125;</span><br><span class="line">user := User&#123;Name: sql.NullString&#123;<span class="string">""</span>, <span class="literal">true</span>&#125;, Age:<span class="number">18</span>&#125;</span><br><span class="line">db.Create(&amp;user)  <span class="comment">// 此时数据库中该条记录name字段的值就是''</span></span><br></pre></td></tr></table></figure>

<h3 id="扩展创建选项"><a href="#扩展创建选项" class="headerlink" title="扩展创建选项"></a>扩展创建选项</h3><p>例如<code>PostgreSQL</code>数据库中可以使用下面的方式实现合并插入, 有则更新, 无则插入。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 为Instert语句添加扩展SQL选项</span></span><br><span class="line">db.Set(<span class="string">"gorm:insert_option"</span>, <span class="string">"ON CONFLICT"</span>).Create(&amp;product)</span><br><span class="line"><span class="comment">// INSERT INTO products (name, code) VALUES ("name", "code") ON CONFLICT;</span></span><br></pre></td></tr></table></figure>

<h2 id="查询"><a href="#查询" class="headerlink" title="查询"></a>查询</h2><h3 id="一般查询"><a href="#一般查询" class="headerlink" title="一般查询"></a>一般查询</h3><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 根据主键查询第一条记录</span></span><br><span class="line">db.First(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users ORDER BY id LIMIT 1;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 随机获取一条记录</span></span><br><span class="line">db.Take(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users LIMIT 1;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 根据主键查询最后一条记录</span></span><br><span class="line">db.Last(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users ORDER BY id DESC LIMIT 1;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 查询所有的记录</span></span><br><span class="line">db.Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 查询指定的某条记录(仅当主键为整型时可用)</span></span><br><span class="line">db.First(&amp;user, <span class="number">10</span>)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE id = 10;</span></span><br></pre></td></tr></table></figure>

<h3 id="Where-条件"><a href="#Where-条件" class="headerlink" title="Where 条件"></a>Where 条件</h3><h4 id="普通SQL查询"><a href="#普通SQL查询" class="headerlink" title="普通SQL查询"></a>普通SQL查询</h4><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Get first matched record</span></span><br><span class="line">db.Where(<span class="string">"name = ?"</span>, <span class="string">"jinzhu"</span>).First(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = 'jinzhu' limit 1;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Get all matched records</span></span><br><span class="line">db.Where(<span class="string">"name = ?"</span>, <span class="string">"jinzhu"</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = 'jinzhu';</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// &lt;&gt;</span></span><br><span class="line">db.Where(<span class="string">"name &lt;&gt; ?"</span>, <span class="string">"jinzhu"</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name &lt;&gt; 'jinzhu';</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// IN</span></span><br><span class="line">db.Where(<span class="string">"name IN (?)"</span>, []<span class="keyword">string</span>&#123;<span class="string">"jinzhu"</span>, <span class="string">"jinzhu 2"</span>&#125;).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name in ('jinzhu','jinzhu 2');</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// LIKE</span></span><br><span class="line">db.Where(<span class="string">"name LIKE ?"</span>, <span class="string">"%jin%"</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name LIKE '%jin%';</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// AND</span></span><br><span class="line">db.Where(<span class="string">"name = ? AND age &gt;= ?"</span>, <span class="string">"jinzhu"</span>, <span class="string">"22"</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = 'jinzhu' AND age &gt;= 22;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Time</span></span><br><span class="line">db.Where(<span class="string">"updated_at &gt; ?"</span>, lastWeek).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE updated_at &gt; '2000-01-01 00:00:00';</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// BETWEEN</span></span><br><span class="line">db.Where(<span class="string">"created_at BETWEEN ? AND ?"</span>, lastWeek, today).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE created_at BETWEEN '2000-01-01 00:00:00' AND '2000-01-08 00:00:00';</span></span><br></pre></td></tr></table></figure>

<h4 id="Struct-amp-Map查询"><a href="#Struct-amp-Map查询" class="headerlink" title="Struct &amp; Map查询"></a>Struct &amp; Map查询</h4><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Struct</span></span><br><span class="line">db.Where(&amp;User&#123;Name: <span class="string">"jinzhu"</span>, Age: <span class="number">20</span>&#125;).First(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Map</span></span><br><span class="line">db.Where(<span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">interface</span>&#123;&#125;&#123;<span class="string">"name"</span>: <span class="string">"jinzhu"</span>, <span class="string">"age"</span>: <span class="number">20</span>&#125;).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 主键的切片</span></span><br><span class="line">db.Where([]<span class="keyword">int64</span>&#123;<span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>&#125;).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE id IN (20, 21, 22);</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong>当通过结构体进行查询时，GORM将会只通过非零值字段查询，这意味着如果你的字段值为<code>0</code>，<code>&#39;&#39;</code>，<code>false</code>或者其他<code>零值</code>时，将不会被用于构建查询条件，例如：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">db.Where(&amp;User&#123;Name: <span class="string">"jinzhu"</span>, Age: <span class="number">0</span>&#125;).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = "jinzhu";</span></span><br></pre></td></tr></table></figure>

<p>你可以使用指针或实现 Scanner/Valuer 接口来避免这个问题.</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用指针</span></span><br><span class="line"><span class="keyword">type</span> User <span class="keyword">struct</span> &#123;</span><br><span class="line">  gorm.Model</span><br><span class="line">  Name <span class="keyword">string</span></span><br><span class="line">  Age  *<span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 Scanner/Valuer</span></span><br><span class="line"><span class="keyword">type</span> User <span class="keyword">struct</span> &#123;</span><br><span class="line">  gorm.Model</span><br><span class="line">  Name <span class="keyword">string</span></span><br><span class="line">  Age  sql.NullInt64  <span class="comment">// sql.NullInt64 实现了 Scanner/Valuer 接口</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="Not-条件"><a href="#Not-条件" class="headerlink" title="Not 条件"></a>Not 条件</h3><p>作用与 Where 类似的情形如下：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">db.Not(<span class="string">"name"</span>, <span class="string">"jinzhu"</span>).First(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name &lt;&gt; "jinzhu" LIMIT 1;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Not In</span></span><br><span class="line">db.Not(<span class="string">"name"</span>, []<span class="keyword">string</span>&#123;<span class="string">"jinzhu"</span>, <span class="string">"jinzhu 2"</span>&#125;).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2");</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Not In slice of primary keys</span></span><br><span class="line">db.Not([]<span class="keyword">int64</span>&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>&#125;).First(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE id NOT IN (1,2,3);</span></span><br><span class="line"></span><br><span class="line">db.Not([]<span class="keyword">int64</span>&#123;&#125;).First(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Plain SQL</span></span><br><span class="line">db.Not(<span class="string">"name = ?"</span>, <span class="string">"jinzhu"</span>).First(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE NOT(name = "jinzhu");</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Struct</span></span><br><span class="line">db.Not(User&#123;Name: <span class="string">"jinzhu"</span>&#125;).First(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name &lt;&gt; "jinzhu";</span></span><br></pre></td></tr></table></figure>

<h3 id="Or条件"><a href="#Or条件" class="headerlink" title="Or条件"></a>Or条件</h3><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">db.Where(<span class="string">"role = ?"</span>, <span class="string">"admin"</span>).Or(<span class="string">"role = ?"</span>, <span class="string">"super_admin"</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Struct</span></span><br><span class="line">db.Where(<span class="string">"name = 'jinzhu'"</span>).Or(User&#123;Name: <span class="string">"jinzhu 2"</span>&#125;).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2';</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Map</span></span><br><span class="line">db.Where(<span class="string">"name = 'jinzhu'"</span>).Or(<span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">interface</span>&#123;&#125;&#123;<span class="string">"name"</span>: <span class="string">"jinzhu 2"</span>&#125;).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2';</span></span><br></pre></td></tr></table></figure>

<h3 id="内联条件"><a href="#内联条件" class="headerlink" title="内联条件"></a>内联条件</h3><p>作用与<code>Where</code>查询类似，当内联条件与多个<a href="https://www.liwenzhou.com/posts/Go/gorm_crud/#autoid-1-3-1" target="_blank" rel="noopener">立即执行方法</a>一起使用时, 内联条件不会传递给后面的立即执行方法。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 根据主键获取记录 (只适用于整形主键)</span></span><br><span class="line">db.First(&amp;user, <span class="number">23</span>)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE id = 23 LIMIT 1;</span></span><br><span class="line"><span class="comment">// 根据主键获取记录, 如果它是一个非整形主键</span></span><br><span class="line">db.First(&amp;user, <span class="string">"id = ?"</span>, <span class="string">"string_primary_key"</span>)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE id = 'string_primary_key' LIMIT 1;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Plain SQL</span></span><br><span class="line">db.Find(&amp;user, <span class="string">"name = ?"</span>, <span class="string">"jinzhu"</span>)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = "jinzhu";</span></span><br><span class="line"></span><br><span class="line">db.Find(&amp;users, <span class="string">"name &lt;&gt; ? AND age &gt; ?"</span>, <span class="string">"jinzhu"</span>, <span class="number">20</span>)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name &lt;&gt; "jinzhu" AND age &gt; 20;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Struct</span></span><br><span class="line">db.Find(&amp;users, User&#123;Age: <span class="number">20</span>&#125;)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE age = 20;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Map</span></span><br><span class="line">db.Find(&amp;users, <span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">interface</span>&#123;&#125;&#123;<span class="string">"age"</span>: <span class="number">20</span>&#125;)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE age = 20;</span></span><br></pre></td></tr></table></figure>

<h3 id="额外查询选项"><a href="#额外查询选项" class="headerlink" title="额外查询选项"></a>额外查询选项</h3><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 为查询 SQL 添加额外的 SQL 操作</span></span><br><span class="line">db.Set(<span class="string">"gorm:query_option"</span>, <span class="string">"FOR UPDATE"</span>).First(&amp;user, <span class="number">10</span>)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE id = 10 FOR UPDATE;</span></span><br></pre></td></tr></table></figure>

<h3 id="FirstOrInit"><a href="#FirstOrInit" class="headerlink" title="FirstOrInit"></a>FirstOrInit</h3><p>获取匹配的第一条记录，否则根据给定的条件初始化一个新的对象 (仅支持 struct 和 map 条件)</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 未找到</span></span><br><span class="line">db.FirstOrInit(&amp;user, User&#123;Name: <span class="string">"non_existing"</span>&#125;)</span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Name: "non_existing"&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 找到</span></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"Jinzhu"</span>&#125;).FirstOrInit(&amp;user)</span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Id: 111, Name: "Jinzhu", Age: 20&#125;</span></span><br><span class="line">db.FirstOrInit(&amp;user, <span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">interface</span>&#123;&#125;&#123;<span class="string">"name"</span>: <span class="string">"jinzhu"</span>&#125;)</span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Id: 111, Name: "Jinzhu", Age: 20&#125;</span></span><br></pre></td></tr></table></figure>

<h4 id="Attrs"><a href="#Attrs" class="headerlink" title="Attrs"></a>Attrs</h4><p>如果记录未找到，将使用参数初始化 struct.</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 未找到</span></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"non_existing"</span>&#125;).Attrs(User&#123;Age: <span class="number">20</span>&#125;).FirstOrInit(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM USERS WHERE name = 'non_existing';</span></span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Name: "non_existing", Age: 20&#125;</span></span><br><span class="line"></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"non_existing"</span>&#125;).Attrs(<span class="string">"age"</span>, <span class="number">20</span>).FirstOrInit(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM USERS WHERE name = 'non_existing';</span></span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Name: "non_existing", Age: 20&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 找到</span></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"Jinzhu"</span>&#125;).Attrs(User&#123;Age: <span class="number">30</span>&#125;).FirstOrInit(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM USERS WHERE name = jinzhu';</span></span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Id: 111, Name: "Jinzhu", Age: 20&#125;</span></span><br></pre></td></tr></table></figure>

<h4 id="Assign"><a href="#Assign" class="headerlink" title="Assign"></a>Assign</h4><p>不管记录是否找到，都将参数赋值给 struct.</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 未找到</span></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"non_existing"</span>&#125;).Assign(User&#123;Age: <span class="number">20</span>&#125;).FirstOrInit(&amp;user)</span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Name: "non_existing", Age: 20&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 找到</span></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"Jinzhu"</span>&#125;).Assign(User&#123;Age: <span class="number">30</span>&#125;).FirstOrInit(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM USERS WHERE name = jinzhu';</span></span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Id: 111, Name: "Jinzhu", Age: 30&#125;</span></span><br></pre></td></tr></table></figure>

<h3 id="FirstOrCreate"><a href="#FirstOrCreate" class="headerlink" title="FirstOrCreate"></a>FirstOrCreate</h3><p>获取匹配的第一条记录, 否则根据给定的条件创建一个新的记录 (仅支持 struct 和 map 条件)</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 未找到</span></span><br><span class="line">db.FirstOrCreate(&amp;user, User&#123;Name: <span class="string">"non_existing"</span>&#125;)</span><br><span class="line"><span class="comment">//// INSERT INTO "users" (name) VALUES ("non_existing");</span></span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Id: 112, Name: "non_existing"&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 找到</span></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"Jinzhu"</span>&#125;).FirstOrCreate(&amp;user)</span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Id: 111, Name: "Jinzhu"&#125;</span></span><br></pre></td></tr></table></figure>

<h4 id="Attrs-1"><a href="#Attrs-1" class="headerlink" title="Attrs"></a>Attrs</h4><p>如果记录未找到，将使用参数创建 struct 和记录.</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">// 未找到</span></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"non_existing"</span>&#125;).Attrs(User&#123;Age: <span class="number">20</span>&#125;).FirstOrCreate(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = 'non_existing';</span></span><br><span class="line"><span class="comment">//// INSERT INTO "users" (name, age) VALUES ("non_existing", 20);</span></span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Id: 112, Name: "non_existing", Age: 20&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 找到</span></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"jinzhu"</span>&#125;).Attrs(User&#123;Age: <span class="number">30</span>&#125;).FirstOrCreate(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = 'jinzhu';</span></span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Id: 111, Name: "jinzhu", Age: 20&#125;</span></span><br></pre></td></tr></table></figure>

<h4 id="Assign-1"><a href="#Assign-1" class="headerlink" title="Assign"></a>Assign</h4><p>不管记录是否找到，都将参数赋值给 struct 并保存至数据库.</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 未找到</span></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"non_existing"</span>&#125;).Assign(User&#123;Age: <span class="number">20</span>&#125;).FirstOrCreate(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = 'non_existing';</span></span><br><span class="line"><span class="comment">//// INSERT INTO "users" (name, age) VALUES ("non_existing", 20);</span></span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Id: 112, Name: "non_existing", Age: 20&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 找到</span></span><br><span class="line">db.Where(User&#123;Name: <span class="string">"jinzhu"</span>&#125;).Assign(User&#123;Age: <span class="number">30</span>&#125;).FirstOrCreate(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE name = 'jinzhu';</span></span><br><span class="line"><span class="comment">//// UPDATE users SET age=30 WHERE id = 111;</span></span><br><span class="line"><span class="comment">//// user -&gt; User&#123;Id: 111, Name: "jinzhu", Age: 30&#125;</span></span><br></pre></td></tr></table></figure>

<h3 id="高级查询"><a href="#高级查询" class="headerlink" title="高级查询"></a>高级查询</h3><h4 id="子查询"><a href="#子查询" class="headerlink" title="子查询"></a>子查询</h4><p>基于 <code>*gorm.expr</code> 的子查询</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">db.Where(<span class="string">"amount &gt; ?"</span>, db.Table(<span class="string">"orders"</span>).Select(<span class="string">"AVG(amount)"</span>).Where(<span class="string">"state = ?"</span>, <span class="string">"paid"</span>).SubQuery()).Find(&amp;orders)</span><br><span class="line"><span class="comment">// SELECT * FROM "orders"  WHERE "orders"."deleted_at" IS NULL AND (amount &gt; (SELECT AVG(amount) FROM "orders"  WHERE (state = 'paid')));</span></span><br></pre></td></tr></table></figure>

<h4 id="选择字段"><a href="#选择字段" class="headerlink" title="选择字段"></a>选择字段</h4><p>Select，指定你想从数据库中检索出的字段，默认会选择全部字段。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">db.Select(<span class="string">"name, age"</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT name, age FROM users;</span></span><br><span class="line"></span><br><span class="line">db.Select([]<span class="keyword">string</span>&#123;<span class="string">"name"</span>, <span class="string">"age"</span>&#125;).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT name, age FROM users;</span></span><br><span class="line"></span><br><span class="line">db.Table(<span class="string">"users"</span>).Select(<span class="string">"COALESCE(age,?)"</span>, <span class="number">42</span>).Rows()</span><br><span class="line"><span class="comment">//// SELECT COALESCE(age,'42') FROM users;</span></span><br></pre></td></tr></table></figure>

<h4 id="排序"><a href="#排序" class="headerlink" title="排序"></a>排序</h4><p>Order，指定从数据库中检索出记录的顺序。设置第二个参数 reorder 为 <code>true</code> ，可以覆盖前面定义的排序条件。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">db.Order(<span class="string">"age desc, name"</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users ORDER BY age desc, name;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 多字段排序</span></span><br><span class="line">db.Order(<span class="string">"age desc"</span>).Order(<span class="string">"name"</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users ORDER BY age desc, name;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 覆盖排序</span></span><br><span class="line">db.Order(<span class="string">"age desc"</span>).Find(&amp;users1).Order(<span class="string">"age"</span>, <span class="literal">true</span>).Find(&amp;users2)</span><br><span class="line"><span class="comment">//// SELECT * FROM users ORDER BY age desc; (users1)</span></span><br><span class="line"><span class="comment">//// SELECT * FROM users ORDER BY age; (users2)</span></span><br></pre></td></tr></table></figure>

<h4 id="数量"><a href="#数量" class="headerlink" title="数量"></a>数量</h4><p>Limit，指定从数据库检索出的最大记录数。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">db.Limit(<span class="number">3</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users LIMIT 3;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// -1 取消 Limit 条件</span></span><br><span class="line">db.Limit(<span class="number">10</span>).Find(&amp;users1).Limit(<span class="number">-1</span>).Find(&amp;users2)</span><br><span class="line"><span class="comment">//// SELECT * FROM users LIMIT 10; (users1)</span></span><br><span class="line"><span class="comment">//// SELECT * FROM users; (users2)</span></span><br></pre></td></tr></table></figure>

<h4 id="偏移"><a href="#偏移" class="headerlink" title="偏移"></a>偏移</h4><p>Offset，指定开始返回记录前要跳过的记录数。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">db.Offset(<span class="number">3</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users OFFSET 3;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// -1 取消 Offset 条件</span></span><br><span class="line">db.Offset(<span class="number">10</span>).Find(&amp;users1).Offset(<span class="number">-1</span>).Find(&amp;users2)</span><br><span class="line"><span class="comment">//// SELECT * FROM users OFFSET 10; (users1)</span></span><br><span class="line"><span class="comment">//// SELECT * FROM users; (users2)</span></span><br></pre></td></tr></table></figure>

<h4 id="总数"><a href="#总数" class="headerlink" title="总数"></a>总数</h4><p>Count，该 model 能获取的记录总数。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">db.Where(<span class="string">"name = ?"</span>, <span class="string">"jinzhu"</span>).Or(<span class="string">"name = ?"</span>, <span class="string">"jinzhu 2"</span>).Find(&amp;users).Count(&amp;count)</span><br><span class="line"><span class="comment">//// SELECT * from USERS WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (users)</span></span><br><span class="line"><span class="comment">//// SELECT count(*) FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (count)</span></span><br><span class="line"></span><br><span class="line">db.Model(&amp;User&#123;&#125;).Where(<span class="string">"name = ?"</span>, <span class="string">"jinzhu"</span>).Count(&amp;count)</span><br><span class="line"><span class="comment">//// SELECT count(*) FROM users WHERE name = 'jinzhu'; (count)</span></span><br><span class="line"></span><br><span class="line">db.Table(<span class="string">"deleted_users"</span>).Count(&amp;count)</span><br><span class="line"><span class="comment">//// SELECT count(*) FROM deleted_users;</span></span><br><span class="line"></span><br><span class="line">db.Table(<span class="string">"deleted_users"</span>).Select(<span class="string">"count(distinct(name))"</span>).Count(&amp;count)</span><br><span class="line"><span class="comment">//// SELECT count( distinct(name) ) FROM deleted_users; (count)</span></span><br></pre></td></tr></table></figure>

<p><strong>注意</strong> <code>Count</code> 必须是链式查询的最后一个操作 ，因为它会覆盖前面的 <code>SELECT</code>，但如果里面使用了 <code>count</code> 时不会覆盖</p>
<h4 id="Group-amp-Having"><a href="#Group-amp-Having" class="headerlink" title="Group &amp; Having"></a>Group &amp; Having</h4><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">rows, err := db.Table(<span class="string">"orders"</span>).Select(<span class="string">"date(created_at) as date, sum(amount) as total"</span>).Group(<span class="string">"date(created_at)"</span>).Rows()</span><br><span class="line"><span class="keyword">for</span> rows.Next() &#123;</span><br><span class="line">  ...</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用Scan将多条结果扫描进事先准备好的结构体切片中</span></span><br><span class="line"><span class="keyword">type</span> Result <span class="keyword">struct</span> &#123;</span><br><span class="line">	Date time.Time</span><br><span class="line">	Total <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> rets []Result</span><br><span class="line">db.Table(<span class="string">"users"</span>).Select(<span class="string">"date(created_at) as date, sum(age) as total"</span>).Group(<span class="string">"date(created_at)"</span>).Scan(&amp;rets)</span><br><span class="line"></span><br><span class="line">rows, err := db.Table(<span class="string">"orders"</span>).Select(<span class="string">"date(created_at) as date, sum(amount) as total"</span>).Group(<span class="string">"date(created_at)"</span>).Having(<span class="string">"sum(amount) &gt; ?"</span>, <span class="number">100</span>).Rows()</span><br><span class="line"><span class="keyword">for</span> rows.Next() &#123;</span><br><span class="line">  ...</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> Result <span class="keyword">struct</span> &#123;</span><br><span class="line">  Date  time.Time</span><br><span class="line">  Total <span class="keyword">int64</span></span><br><span class="line">&#125;</span><br><span class="line">db.Table(<span class="string">"orders"</span>).Select(<span class="string">"date(created_at) as date, sum(amount) as total"</span>).Group(<span class="string">"date(created_at)"</span>).Having(<span class="string">"sum(amount) &gt; ?"</span>, <span class="number">100</span>).Scan(&amp;results)</span><br></pre></td></tr></table></figure>

<h4 id="连接"><a href="#连接" class="headerlink" title="连接"></a>连接</h4><p>Joins，指定连接条件</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">rows, err := db.Table(<span class="string">"users"</span>).Select(<span class="string">"users.name, emails.email"</span>).Joins(<span class="string">"left join emails on emails.user_id = users.id"</span>).Rows()</span><br><span class="line"><span class="keyword">for</span> rows.Next() &#123;</span><br><span class="line">  ...</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">db.Table(<span class="string">"users"</span>).Select(<span class="string">"users.name, emails.email"</span>).Joins(<span class="string">"left join emails on emails.user_id = users.id"</span>).Scan(&amp;results)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 多连接及参数</span></span><br><span class="line">db.Joins(<span class="string">"JOIN emails ON emails.user_id = users.id AND emails.email = ?"</span>, <span class="string">"jinzhu@example.org"</span>).Joins(<span class="string">"JOIN credit_cards ON credit_cards.user_id = users.id"</span>).Where(<span class="string">"credit_cards.number = ?"</span>, <span class="string">"411111111111"</span>).Find(&amp;user)</span><br></pre></td></tr></table></figure>

<h3 id="Pluck"><a href="#Pluck" class="headerlink" title="Pluck"></a>Pluck</h3><p>Pluck，查询 model 中的一个列作为切片，如果您想要查询多个列，您应该使用 <a href="https://www.liwenzhou.com/posts/Go/gorm_crud/#Scan" target="_blank" rel="noopener"><code>Scan</code></a></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> ages []<span class="keyword">int64</span></span><br><span class="line">db.Find(&amp;users).Pluck(<span class="string">"age"</span>, &amp;ages)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> names []<span class="keyword">string</span></span><br><span class="line">db.Model(&amp;User&#123;&#125;).Pluck(<span class="string">"name"</span>, &amp;names)</span><br><span class="line"></span><br><span class="line">db.Table(<span class="string">"deleted_users"</span>).Pluck(<span class="string">"name"</span>, &amp;names)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 想查询多个字段？ 这样做：</span></span><br><span class="line">db.Select(<span class="string">"name, age"</span>).Find(&amp;users)</span><br></pre></td></tr></table></figure>

<h3 id="扫描"><a href="#扫描" class="headerlink" title="扫描"></a>扫描</h3><p>Scan，扫描结果至一个 struct.</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> Result <span class="keyword">struct</span> &#123;</span><br><span class="line">  Name <span class="keyword">string</span></span><br><span class="line">  Age  <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> result Result</span><br><span class="line">db.Table(<span class="string">"users"</span>).Select(<span class="string">"name, age"</span>).Where(<span class="string">"name = ?"</span>, <span class="string">"Antonio"</span>).Scan(&amp;result)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> results []Result</span><br><span class="line">db.Table(<span class="string">"users"</span>).Select(<span class="string">"name, age"</span>).Where(<span class="string">"id &gt; ?"</span>, <span class="number">0</span>).Scan(&amp;results)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 原生 SQL</span></span><br><span class="line">db.Raw(<span class="string">"SELECT name, age FROM users WHERE name = ?"</span>, <span class="string">"Antonio"</span>).Scan(&amp;result)</span><br></pre></td></tr></table></figure>

<h2 id="链式操作相关"><a href="#链式操作相关" class="headerlink" title="链式操作相关"></a>链式操作相关</h2><h3 id="链式操作"><a href="#链式操作" class="headerlink" title="链式操作"></a>链式操作</h3><p>Method Chaining，Gorm 实现了链式操作接口，所以你可以把代码写成这样：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建一个查询</span></span><br><span class="line">tx := db.Where(<span class="string">"name = ?"</span>, <span class="string">"jinzhu"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加更多条件</span></span><br><span class="line"><span class="keyword">if</span> someCondition &#123;</span><br><span class="line">  tx = tx.Where(<span class="string">"age = ?"</span>, <span class="number">20</span>)</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">  tx = tx.Where(<span class="string">"age = ?"</span>, <span class="number">30</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> yetAnotherCondition &#123;</span><br><span class="line">  tx = tx.Where(<span class="string">"active = ?"</span>, <span class="number">1</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在调用立即执行方法前不会生成<code>Query</code>语句，借助这个特性你可以创建一个函数来处理一些通用逻辑。</p>
<h3 id="立即执行方法"><a href="#立即执行方法" class="headerlink" title="立即执行方法"></a>立即执行方法</h3><p>Immediate methods ，立即执行方法是指那些会立即生成<code>SQL</code>语句并发送到数据库的方法, 他们一般是<code>CRUD</code>方法，比如：</p>
<p><code>Create</code>, <code>First</code>, <code>Find</code>, <code>Take</code>, <code>Save</code>, <code>UpdateXXX</code>, <code>Delete</code>, <code>Scan</code>, <code>Row</code>, <code>Rows</code>…</p>
<p>这有一个基于上面链式方法代码的立即执行方法的例子：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tx.Find(&amp;user)</span><br></pre></td></tr></table></figure>

<p>生成的SQL语句如下：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> <span class="keyword">users</span> <span class="keyword">where</span> <span class="keyword">name</span> = <span class="string">'jinzhu'</span> <span class="keyword">AND</span> age = <span class="number">30</span> <span class="keyword">AND</span> active = <span class="number">1</span>;</span><br></pre></td></tr></table></figure>

<h3 id="范围"><a href="#范围" class="headerlink" title="范围"></a>范围</h3><p><code>Scopes</code>，Scope是建立在链式操作的基础之上的。</p>
<p>基于它，你可以抽取一些通用逻辑，写出更多可重用的函数库。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">AmountGreaterThan1000</span><span class="params">(db *gorm.DB)</span> *<span class="title">gorm</span>.<span class="title">DB</span></span> &#123;</span><br><span class="line">  <span class="keyword">return</span> db.Where(<span class="string">"amount &gt; ?"</span>, <span class="number">1000</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">PaidWithCreditCard</span><span class="params">(db *gorm.DB)</span> *<span class="title">gorm</span>.<span class="title">DB</span></span> &#123;</span><br><span class="line">  <span class="keyword">return</span> db.Where(<span class="string">"pay_mode_sign = ?"</span>, <span class="string">"C"</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">PaidWithCod</span><span class="params">(db *gorm.DB)</span> *<span class="title">gorm</span>.<span class="title">DB</span></span> &#123;</span><br><span class="line">  <span class="keyword">return</span> db.Where(<span class="string">"pay_mode_sign = ?"</span>, <span class="string">"C"</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">OrderStatus</span><span class="params">(status []<span class="keyword">string</span>)</span> <span class="title">func</span> <span class="params">(db *gorm.DB)</span> *<span class="title">gorm</span>.<span class="title">DB</span></span> &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">func</span> <span class="params">(db *gorm.DB)</span> *<span class="title">gorm</span>.<span class="title">DB</span></span> &#123;</span><br><span class="line">    <span class="keyword">return</span> db.Scopes(AmountGreaterThan1000).Where(<span class="string">"status IN (?)"</span>, status)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">db.Scopes(AmountGreaterThan1000, PaidWithCreditCard).Find(&amp;orders)</span><br><span class="line"><span class="comment">// 查找所有金额大于 1000 的信用卡订单</span></span><br><span class="line"></span><br><span class="line">db.Scopes(AmountGreaterThan1000, PaidWithCod).Find(&amp;orders)</span><br><span class="line"><span class="comment">// 查找所有金额大于 1000 的 COD 订单</span></span><br><span class="line"></span><br><span class="line">db.Scopes(AmountGreaterThan1000, OrderStatus([]<span class="keyword">string</span>&#123;<span class="string">"paid"</span>, <span class="string">"shipped"</span>&#125;)).Find(&amp;orders)</span><br><span class="line"><span class="comment">// 查找所有金额大于 1000 且已付款或者已发货的订单</span></span><br></pre></td></tr></table></figure>

<h3 id="多个立即执行方法"><a href="#多个立即执行方法" class="headerlink" title="多个立即执行方法"></a>多个立即执行方法</h3><p>Multiple Immediate Methods，在 GORM 中使用多个立即执行方法时，后一个立即执行方法会复用前一个<strong>立即执行方法</strong>的条件 (不包括内联条件) 。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.Where(<span class="string">"name LIKE ?"</span>, <span class="string">"jinzhu%"</span>).Find(&amp;users, <span class="string">"id IN (?)"</span>, []<span class="keyword">int</span>&#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;).Count(&amp;count)</span><br></pre></td></tr></table></figure>

<p>生成的 Sql</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> <span class="keyword">users</span> <span class="keyword">WHERE</span> <span class="keyword">name</span> <span class="keyword">LIKE</span> <span class="string">'jinzhu%'</span> <span class="keyword">AND</span> <span class="keyword">id</span> <span class="keyword">IN</span> (<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="keyword">count</span>(*) <span class="keyword">FROM</span> <span class="keyword">users</span> <span class="keyword">WHERE</span> <span class="keyword">name</span> <span class="keyword">LIKE</span> <span class="string">'jinzhu%'</span></span><br></pre></td></tr></table></figure>

<h2 id="更新"><a href="#更新" class="headerlink" title="更新"></a>更新</h2><h3 id="更新所有字段"><a href="#更新所有字段" class="headerlink" title="更新所有字段"></a>更新所有字段</h3><p><code>Save()</code>默认会更新该对象的所有字段，即使你没有赋值。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">db.First(&amp;user)</span><br><span class="line"></span><br><span class="line">user.Name = <span class="string">"七米"</span></span><br><span class="line">user.Age = <span class="number">99</span></span><br><span class="line">db.Save(&amp;user)</span><br><span class="line"></span><br><span class="line"><span class="comment">////  UPDATE `users` SET `created_at` = '2020-02-16 12:52:20', `updated_at` = '2020-02-16 12:54:55', `deleted_at` = NULL, `name` = '七米', `age` = 99, `active` = true  WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1</span></span><br></pre></td></tr></table></figure>

<h3 id="更新修改字段"><a href="#更新修改字段" class="headerlink" title="更新修改字段"></a>更新修改字段</h3><p>如果你只希望更新指定字段，可以使用<code>Update</code>或者<code>Updates</code></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 更新单个属性，如果它有变化</span></span><br><span class="line">db.Model(&amp;user).Update(<span class="string">"name"</span>, <span class="string">"hello"</span>)</span><br><span class="line"><span class="comment">//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 根据给定的条件更新单个属性</span></span><br><span class="line">db.Model(&amp;user).Where(<span class="string">"active = ?"</span>, <span class="literal">true</span>).Update(<span class="string">"name"</span>, <span class="string">"hello"</span>)</span><br><span class="line"><span class="comment">//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 map 更新多个属性，只会更新其中有变化的属性</span></span><br><span class="line">db.Model(&amp;user).Updates(<span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">interface</span>&#123;&#125;&#123;<span class="string">"name"</span>: <span class="string">"hello"</span>, <span class="string">"age"</span>: <span class="number">18</span>, <span class="string">"active"</span>: <span class="literal">false</span>&#125;)</span><br><span class="line"><span class="comment">//// UPDATE users SET name='hello', age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 struct 更新多个属性，只会更新其中有变化且为非零值的字段</span></span><br><span class="line">db.Model(&amp;user).Updates(User&#123;Name: <span class="string">"hello"</span>, Age: <span class="number">18</span>&#125;)</span><br><span class="line"><span class="comment">//// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 警告：当使用 struct 更新时，GORM只会更新那些非零值的字段</span></span><br><span class="line"><span class="comment">// 对于下面的操作，不会发生任何更新，"", 0, false 都是其类型的零值</span></span><br><span class="line">db.Model(&amp;user).Updates(User&#123;Name: <span class="string">""</span>, Age: <span class="number">0</span>, Active: <span class="literal">false</span>&#125;)</span><br></pre></td></tr></table></figure>

<h3 id="更新选定字段"><a href="#更新选定字段" class="headerlink" title="更新选定字段"></a>更新选定字段</h3><p>如果你想更新或忽略某些字段，你可以使用 <code>Select</code>，<code>Omit</code></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">db.Model(&amp;user).Select(<span class="string">"name"</span>).Updates(<span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">interface</span>&#123;&#125;&#123;<span class="string">"name"</span>: <span class="string">"hello"</span>, <span class="string">"age"</span>: <span class="number">18</span>, <span class="string">"active"</span>: <span class="literal">false</span>&#125;)</span><br><span class="line"><span class="comment">//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;</span></span><br><span class="line"></span><br><span class="line">db.Model(&amp;user).Omit(<span class="string">"name"</span>).Updates(<span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">interface</span>&#123;&#125;&#123;<span class="string">"name"</span>: <span class="string">"hello"</span>, <span class="string">"age"</span>: <span class="number">18</span>, <span class="string">"active"</span>: <span class="literal">false</span>&#125;)</span><br><span class="line"><span class="comment">//// UPDATE users SET age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;</span></span><br></pre></td></tr></table></figure>

<h3 id="无Hooks更新"><a href="#无Hooks更新" class="headerlink" title="无Hooks更新"></a>无Hooks更新</h3><p>上面的更新操作会自动运行 model 的 <code>BeforeUpdate</code>, <code>AfterUpdate</code> 方法，更新 <code>UpdatedAt</code> 时间戳, 在更新时保存其 <code>Associations</code>, 如果你不想调用这些方法，你可以使用 <code>UpdateColumn</code>， <code>UpdateColumns</code></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 更新单个属性，类似于 `Update`</span></span><br><span class="line">db.Model(&amp;user).UpdateColumn(<span class="string">"name"</span>, <span class="string">"hello"</span>)</span><br><span class="line"><span class="comment">//// UPDATE users SET name='hello' WHERE id = 111;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 更新多个属性，类似于 `Updates`</span></span><br><span class="line">db.Model(&amp;user).UpdateColumns(User&#123;Name: <span class="string">"hello"</span>, Age: <span class="number">18</span>&#125;)</span><br><span class="line"><span class="comment">//// UPDATE users SET name='hello', age=18 WHERE id = 111;</span></span><br></pre></td></tr></table></figure>

<h3 id="批量更新"><a href="#批量更新" class="headerlink" title="批量更新"></a>批量更新</h3><p>批量更新时<code>Hooks（钩子函数）</code>不会运行。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">db.Table(<span class="string">"users"</span>).Where(<span class="string">"id IN (?)"</span>, []<span class="keyword">int</span>&#123;<span class="number">10</span>, <span class="number">11</span>&#125;).Updates(<span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">interface</span>&#123;&#125;&#123;<span class="string">"name"</span>: <span class="string">"hello"</span>, <span class="string">"age"</span>: <span class="number">18</span>&#125;)</span><br><span class="line"><span class="comment">//// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11);</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 struct 更新时，只会更新非零值字段，若想更新所有字段，请使用map[string]interface&#123;&#125;</span></span><br><span class="line">db.Model(User&#123;&#125;).Updates(User&#123;Name: <span class="string">"hello"</span>, Age: <span class="number">18</span>&#125;)</span><br><span class="line"><span class="comment">//// UPDATE users SET name='hello', age=18;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 `RowsAffected` 获取更新记录总数</span></span><br><span class="line">db.Model(User&#123;&#125;).Updates(User&#123;Name: <span class="string">"hello"</span>, Age: <span class="number">18</span>&#125;).RowsAffected</span><br></pre></td></tr></table></figure>

<h3 id="使用SQL表达式更新"><a href="#使用SQL表达式更新" class="headerlink" title="使用SQL表达式更新"></a>使用SQL表达式更新</h3><p>先查询表中的第一条数据保存至user变量。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> user User</span><br><span class="line">db.First(&amp;user)</span><br><span class="line">db.Model(&amp;user).Update(<span class="string">"age"</span>, gorm.Expr(<span class="string">"age * ? + ?"</span>, <span class="number">2</span>, <span class="number">100</span>))</span><br><span class="line"><span class="comment">//// UPDATE `users` SET `age` = age * 2 + 100, `updated_at` = '2020-02-16 13:10:20'  WHERE `users`.`id` = 1;</span></span><br><span class="line"></span><br><span class="line">db.Model(&amp;user).Updates(<span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">interface</span>&#123;&#125;&#123;<span class="string">"age"</span>: gorm.Expr(<span class="string">"age * ? + ?"</span>, <span class="number">2</span>, <span class="number">100</span>)&#125;)</span><br><span class="line"><span class="comment">//// UPDATE "users" SET "age" = age * '2' + '100', "updated_at" = '2020-02-16 13:05:51' WHERE `users`.`id` = 1;</span></span><br><span class="line"></span><br><span class="line">db.Model(&amp;user).UpdateColumn(<span class="string">"age"</span>, gorm.Expr(<span class="string">"age - ?"</span>, <span class="number">1</span>))</span><br><span class="line"><span class="comment">//// UPDATE "users" SET "age" = age - 1 WHERE "id" = '1';</span></span><br><span class="line"></span><br><span class="line">db.Model(&amp;user).Where(<span class="string">"age &gt; 10"</span>).UpdateColumn(<span class="string">"age"</span>, gorm.Expr(<span class="string">"age - ?"</span>, <span class="number">1</span>))</span><br><span class="line"><span class="comment">//// UPDATE "users" SET "age" = age - 1 WHERE "id" = '1' AND quantity &gt; 10;</span></span><br></pre></td></tr></table></figure>

<h3 id="修改Hooks中的值"><a href="#修改Hooks中的值" class="headerlink" title="修改Hooks中的值"></a>修改Hooks中的值</h3><p>如果你想修改 <code>BeforeUpdate</code>, <code>BeforeSave</code> 等 Hooks 中更新的值，你可以使用 <code>scope.SetColumn</code>, 例如：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(user *User)</span> <span class="title">BeforeSave</span><span class="params">(scope *gorm.Scope)</span> <span class="params">(err error)</span></span> &#123;</span><br><span class="line">  <span class="keyword">if</span> pw, err := bcrypt.GenerateFromPassword(user.Password, <span class="number">0</span>); err == <span class="literal">nil</span> &#123;</span><br><span class="line">    scope.SetColumn(<span class="string">"EncryptedPassword"</span>, pw)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="其它更新选项"><a href="#其它更新选项" class="headerlink" title="其它更新选项"></a>其它更新选项</h3><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 为 update SQL 添加其它的 SQL</span></span><br><span class="line">db.Model(&amp;user).Set(<span class="string">"gorm:update_option"</span>, <span class="string">"OPTION (OPTIMIZE FOR UNKNOWN)"</span>).Update(<span class="string">"name"</span>, <span class="string">"hello"</span>)</span><br><span class="line"><span class="comment">//// UPDATE users SET name='hello', updated_at = '2013-11-17 21:34:10' WHERE id=111 OPTION (OPTIMIZE FOR UNKNOWN);</span></span><br></pre></td></tr></table></figure>

<h2 id="删除"><a href="#删除" class="headerlink" title="删除"></a>删除</h2><h3 id="删除记录"><a href="#删除记录" class="headerlink" title="删除记录"></a>删除记录</h3><p><strong>警告</strong> 删除记录时，请确保主键字段有值，GORM 会通过主键去删除记录，如果主键为空，GORM 会删除该 model 的所有记录。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 删除现有记录</span></span><br><span class="line">db.Delete(&amp;email)</span><br><span class="line"><span class="comment">//// DELETE from emails where id=10;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 为删除 SQL 添加额外的 SQL 操作</span></span><br><span class="line">db.Set(<span class="string">"gorm:delete_option"</span>, <span class="string">"OPTION (OPTIMIZE FOR UNKNOWN)"</span>).Delete(&amp;email)</span><br><span class="line"><span class="comment">//// DELETE from emails where id=10 OPTION (OPTIMIZE FOR UNKNOWN);</span></span><br></pre></td></tr></table></figure>

<h3 id="批量删除"><a href="#批量删除" class="headerlink" title="批量删除"></a>批量删除</h3><p>删除全部匹配的记录</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">db.Where(<span class="string">"email LIKE ?"</span>, <span class="string">"%jinzhu%"</span>).Delete(Email&#123;&#125;)</span><br><span class="line"><span class="comment">//// DELETE from emails where email LIKE "%jinzhu%";</span></span><br><span class="line"></span><br><span class="line">db.Delete(Email&#123;&#125;, <span class="string">"email LIKE ?"</span>, <span class="string">"%jinzhu%"</span>)</span><br><span class="line"><span class="comment">//// DELETE from emails where email LIKE "%jinzhu%";</span></span><br></pre></td></tr></table></figure>

<h3 id="软删除"><a href="#软删除" class="headerlink" title="软删除"></a>软删除</h3><p>如果一个 model 有 <code>DeletedAt</code> 字段，他将自动获得软删除的功能！ 当调用 <code>Delete</code> 方法时， 记录不会真正的从数据库中被删除， 只会将<code>DeletedAt</code> 字段的值会被设置为当前时间</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">db.Delete(&amp;user)</span><br><span class="line"><span class="comment">//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 批量删除</span></span><br><span class="line">db.Where(<span class="string">"age = ?"</span>, <span class="number">20</span>).Delete(&amp;User&#123;&#125;)</span><br><span class="line"><span class="comment">//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 查询记录时会忽略被软删除的记录</span></span><br><span class="line">db.Where(<span class="string">"age = 20"</span>).Find(&amp;user)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Unscoped 方法可以查询被软删除的记录</span></span><br><span class="line">db.Unscoped().Where(<span class="string">"age = 20"</span>).Find(&amp;users)</span><br><span class="line"><span class="comment">//// SELECT * FROM users WHERE age = 20;</span></span><br></pre></td></tr></table></figure>

<h3 id="物理删除"><a href="#物理删除" class="headerlink" title="物理删除"></a>物理删除</h3><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Unscoped 方法可以物理删除记录</span></span><br><span class="line">db.Unscoped().Delete(&amp;order)</span><br><span class="line"><span class="comment">//// DELETE FROM orders WHERE id=10;</span></span><br></pre></td></tr></table></figure></section>
    <!-- Tags START -->
    
    <!-- Tags END -->
    <!-- NAV START -->
    
  <div class="nav-container">
    <!-- reverse left and right to put prev and next in a more logic postition -->
    
      <a class="nav-left" href="/go/4-Go%E8%AF%AD%E8%A8%80%E6%A1%86%E6%9E%B6/4-1-gin%E6%A1%86%E6%9E%B6/7-GORM%E4%BD%BF%E7%94%A8/">
        <span class="nav-arrow">← </span>
        
          go/4-Go语言框架/4-1-gin框架/7-GORM使用
        
      </a>
    
    
      <a class="nav-right" href="/python/Django%E6%A1%86%E6%9E%B6/19-Django%E9%AB%98%E7%BA%A7%E4%B9%8B-%E7%BC%93%E5%AD%98/">
        
          python/Django框架/19-Django高级之-缓存
        
        <span class="nav-arrow"> →</span>
      </a>
    
  </div>

    <!-- NAV END -->
    <!-- 打赏 START -->
    
      <div class="money-like">
        <div class="reward-btn">
          赏
          <span class="money-code">
            <span class="alipay-code">
              <div class="code-image"></div>
              <b>使用支付宝打赏</b>
            </span>
            <span class="wechat-code">
              <div class="code-image"></div>
              <b>使用微信打赏</b>
            </span>
          </span>
        </div>
        <p class="notice">点击上方按钮,请我喝杯咖啡！</p>
      </div>
    
    <!-- 打赏 END -->
    <!-- 二维码 START -->
    
      <div class="qrcode">
        <canvas id="share-qrcode"></canvas>
        <p class="notice">扫描二维码，分享此文章</p>
      </div>
    
    <!-- 二维码 END -->
    
      <!-- Gitment START -->
      <div id="comments"></div>
      <!-- Gitment END -->
    
  </article>
  <!-- Article END -->
  <!-- Catalog START -->
  
    <aside class="catalog-container">
  <div class="toc-main">
  <!-- 不蒜子统计 -->
    <strong class="toc-title">目录</strong>
    
      <ol class="toc-nav"><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#CRUD"><span class="toc-nav-text">CRUD</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#创建"><span class="toc-nav-text">创建</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#创建记录"><span class="toc-nav-text">创建记录</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#默认值"><span class="toc-nav-text">默认值</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#使用指针方式实现零值存入数据库"><span class="toc-nav-text">使用指针方式实现零值存入数据库</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#使用Scanner-Valuer接口方式实现零值存入数据库"><span class="toc-nav-text">使用Scanner&#x2F;Valuer接口方式实现零值存入数据库</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#扩展创建选项"><span class="toc-nav-text">扩展创建选项</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#查询"><span class="toc-nav-text">查询</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#一般查询"><span class="toc-nav-text">一般查询</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#Where-条件"><span class="toc-nav-text">Where 条件</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#普通SQL查询"><span class="toc-nav-text">普通SQL查询</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#Struct-amp-Map查询"><span class="toc-nav-text">Struct &amp; Map查询</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#Not-条件"><span class="toc-nav-text">Not 条件</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#Or条件"><span class="toc-nav-text">Or条件</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#内联条件"><span class="toc-nav-text">内联条件</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#额外查询选项"><span class="toc-nav-text">额外查询选项</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#FirstOrInit"><span class="toc-nav-text">FirstOrInit</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#Attrs"><span class="toc-nav-text">Attrs</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#Assign"><span class="toc-nav-text">Assign</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#FirstOrCreate"><span class="toc-nav-text">FirstOrCreate</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#Attrs-1"><span class="toc-nav-text">Attrs</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#Assign-1"><span class="toc-nav-text">Assign</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#高级查询"><span class="toc-nav-text">高级查询</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#子查询"><span class="toc-nav-text">子查询</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#选择字段"><span class="toc-nav-text">选择字段</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#排序"><span class="toc-nav-text">排序</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#数量"><span class="toc-nav-text">数量</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#偏移"><span class="toc-nav-text">偏移</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#总数"><span class="toc-nav-text">总数</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#Group-amp-Having"><span class="toc-nav-text">Group &amp; Having</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#连接"><span class="toc-nav-text">连接</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#Pluck"><span class="toc-nav-text">Pluck</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#扫描"><span class="toc-nav-text">扫描</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#链式操作相关"><span class="toc-nav-text">链式操作相关</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#链式操作"><span class="toc-nav-text">链式操作</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#立即执行方法"><span class="toc-nav-text">立即执行方法</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#范围"><span class="toc-nav-text">范围</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#多个立即执行方法"><span class="toc-nav-text">多个立即执行方法</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#更新"><span class="toc-nav-text">更新</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#更新所有字段"><span class="toc-nav-text">更新所有字段</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#更新修改字段"><span class="toc-nav-text">更新修改字段</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#更新选定字段"><span class="toc-nav-text">更新选定字段</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#无Hooks更新"><span class="toc-nav-text">无Hooks更新</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#批量更新"><span class="toc-nav-text">批量更新</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#使用SQL表达式更新"><span class="toc-nav-text">使用SQL表达式更新</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#修改Hooks中的值"><span class="toc-nav-text">修改Hooks中的值</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#其它更新选项"><span class="toc-nav-text">其它更新选项</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#删除"><span class="toc-nav-text">删除</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#删除记录"><span class="toc-nav-text">删除记录</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#批量删除"><span class="toc-nav-text">批量删除</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#软删除"><span class="toc-nav-text">软删除</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#物理删除"><span class="toc-nav-text">物理删除</span></a></li></ol></li></ol></li></ol>
    
  </div>
</aside>
  
  <!-- Catalog END -->
</main>

<script>
  (function () {
    var url = 'http://www.liuqingzheng.top/go/4-Go语言框架/4-1-gin框架/8-GORM增删查改/';
    var banner = ''
    if (banner !== '' && banner !== 'undefined' && banner !== 'null') {
      $('#article-banner').css({
        'background-image': 'url(' + banner + ')'
      })
    } else {
      $('#article-banner').geopattern(url)
    }
    $('.header').removeClass('fixed-header')

    // error image
    $(".markdown-content img").on('error', function() {
      $(this).attr('src', 'http://file.muyutech.com/error-img.png')
      $(this).css({
        'cursor': 'default'
      })
    })

    // zoom image
    $(".markdown-content img").on('click', function() {
      var src = $(this).attr('src')
      if (src !== 'http://file.muyutech.com/error-img.png') {
        var imageW = $(this).width()
        var imageH = $(this).height()

        var zoom = ($(window).width() * 0.95 / imageW).toFixed(2)
        zoom = zoom < 1 ? 1 : zoom
        zoom = zoom > 2 ? 2 : zoom
        var transY = (($(window).height() - imageH) / 2).toFixed(2)

        $('body').append('<div class="image-view-wrap"><div class="image-view-inner"><img src="'+ src +'" /></div></div>')
        $('.image-view-wrap').addClass('wrap-active')
        $('.image-view-wrap img').css({
          'width': `${imageW}`,
          'transform': `translate3d(0, ${transY}px, 0) scale3d(${zoom}, ${zoom}, 1)`
        })
        $('html').css('overflow', 'hidden')

        $('.image-view-wrap').on('click', function() {
          $(this).remove()
          $('html').attr('style', '')
        })
      }
    })
  })();
</script>


  <script>
    var qr = new QRious({
      element: document.getElementById('share-qrcode'),
      value: document.location.href
    });
  </script>



  <script>
    var gitmentConfig = "liuqingzheng";
    if (gitmentConfig !== 'undefined') {
      var gitment = new Gitment({
        id: "go/4-Go语言框架/4-1-gin框架/8-GORM增删查改",
        owner: "liuqingzheng",
        repo: "FuckBlog",
        oauth: {
          client_id: "32a4076431cf39d0ecea",
          client_secret: "94484bd79b3346a949acb2fda3c8a76ce16990c6"
        },
        theme: {
          render(state, instance) {
            const container = document.createElement('div')
            container.lang = "en-US"
            container.className = 'gitment-container gitment-root-container'
            container.appendChild(instance.renderHeader(state, instance))
            container.appendChild(instance.renderEditor(state, instance))
            container.appendChild(instance.renderComments(state, instance))
            container.appendChild(instance.renderFooter(state, instance))
            return container;
          }
        }
      })
      gitment.render(document.getElementById('comments'))
    }
  </script>




    <div class="scroll-top">
  <span class="arrow-icon"></span>
</div>
    <footer class="app-footer">
<!-- 不蒜子统计 -->
<span id="busuanzi_container_site_pv">
     本站总访问量<span id="busuanzi_value_site_pv"></span>次
</span>
<span class="post-meta-divider">|</span>
<span id="busuanzi_container_site_uv" style='display:none'>
     本站访客数<span id="busuanzi_value_site_uv"></span>人
</span>
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>



  <p class="copyright">
    &copy; 2021 | Proudly powered by <a href="https://www.cnblogs.com/xiaoyuanqujing" target="_blank">小猿取经</a>
    <br>
    Theme by <a href="https://www.cnblogs.com/xiaoyuanqujing" target="_blank" rel="noopener">小猿取经</a>
  </p>
</footer>

<script>
  function async(u, c) {
    var d = document, t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
    s.parentNode.insertBefore(o, s);
  }
</script>
<script>
  async("//cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js", function(){
    FastClick.attach(document.body);
  })
</script>

<script>
  var hasLine = 'true';
  async("//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js", function(){
    $('figure pre').each(function(i, block) {
      var figure = $(this).parents('figure');
      if (hasLine === 'false') {
        figure.find('.gutter').hide();
      }
      var lang = figure.attr('class').split(' ')[1] || 'code';
      var codeHtml = $(this).html();
      var codeTag = document.createElement('code');
      codeTag.className = lang;
      codeTag.innerHTML = codeHtml;
      $(this).attr('class', '').empty().html(codeTag);
      figure.attr('data-lang', lang.toUpperCase());
      hljs.highlightBlock(block);
    });
  })
</script>





<!-- Baidu Tongji -->

<script>
    var _baId = 'c5fd96eee1193585be191f318c3fa725';
    // Originial
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?" + _baId;
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
</script>


<script src="/js/script.js"></script>


<script src="/js/search.js"></script>


<script src="/js/load.js"></script>



  <span class="local-search local-search-google local-search-plugin" style="right: 50px;top: 70px;;position:absolute;z-index:2;">
      <input type="search" placeholder="站内搜索" id="local-search-input" class="local-search-input-cls" style="">
      <div id="local-search-result" class="local-search-result-cls"></div>
  </span>


  </body>
</html>